﻿using System;
using System.Windows.Forms;

namespace DBLGen.UI.Design.Query
{
	public class CalendarColumn : DataGridViewColumn
	{
		public CalendarColumn()
			: base(new CalendarCell())
		{
		}

		public override DataGridViewCell CellTemplate
		{
			get
			{
				return base.CellTemplate;
			}
			set
			{
				// Ensure that the cell used for the template is a CalendarCell.
				if (value != null &&
						!value.GetType().IsAssignableFrom(typeof(CalendarCell)))
				{
					throw new InvalidCastException("Must be a CalendarCell");
				}
				base.CellTemplate = value;
			}
		}
	}

	public class CalendarCell : DataGridViewTextBoxCell
	{

		public CalendarCell()
			: base()
		{
			// Use the short date format.
			this.Style.Format = "d";
		}

		public override void InitializeEditingControl(int rowIndex, object
				initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
		{
			// Set the value of the editing control to the current cell value.
			base.InitializeEditingControl(rowIndex, initialFormattedValue,
					dataGridViewCellStyle);
			CalendarEditingControl ctl =
					DataGridView.EditingControl as CalendarEditingControl;
			ctl.Value = (DateTime)this.Value;
		}

		public override Type EditType
		{
			get
			{
				// Return the type of the editing contol that CalendarCell uses.
				return typeof(CalendarEditingControl);
			}
		}

		public override Type ValueType
		{
			get
			{
				// Return the type of the value that CalendarCell contains.
				return typeof(DateTime);
			}
		}

		public override object DefaultNewRowValue
		{
			get
			{
				// Use the current date and time as the default value.
				return DateTime.Now;
			}
		}
	}

	class CalendarEditingControl : DateTimePicker, IDataGridViewEditingControl
	{
		DataGridView dataGridView;
		private bool valueChanged = false;
		int rowIndex;

		public CalendarEditingControl()
		{
			this.Format = DateTimePickerFormat.Short;
		}

		// Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
		// property.
		public object EditingControlFormattedValue
		{
			get
			{
				return this.Value.ToShortDateString();
			}
			set
			{
				if (value is String)
				{
					this.Value = DateTime.Parse((String)value);
				}
			}
		}

		// Implements the 
		// IDataGridViewEditingControl.GetEditingControlFormattedValue method.
		public object GetEditingControlFormattedValue(
				DataGridViewDataErrorContexts context)
		{
			return EditingControlFormattedValue;
		}

		// Implements the 
		// IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
		public void ApplyCellStyleToEditingControl(
				DataGridViewCellStyle dataGridViewCellStyle)
		{
			this.Font = dataGridViewCellStyle.Font;
			this.CalendarForeColor = dataGridViewCellStyle.ForeColor;
			this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;
		}

		// Implements the IDataGridViewEditingControl.EditingControlRowIndex 
		// property.
		public int EditingControlRowIndex
		{
			get
			{
				return rowIndex;
			}
			set
			{
				rowIndex = value;
			}
		}

		// Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
		// method.
		public bool EditingControlWantsInputKey(
				Keys key, bool dataGridViewWantsInputKey)
		{
			// Let the DateTimePicker handle the keys listed.
			switch (key & Keys.KeyCode)
			{
				case Keys.Left:
				case Keys.Up:
				case Keys.Down:
				case Keys.Right:
				case Keys.Home:
				case Keys.End:
				case Keys.PageDown:
				case Keys.PageUp:
					return true;
				default:
					return !dataGridViewWantsInputKey;
			}
		}

		// Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
		// method.
		public void PrepareEditingControlForEdit(bool selectAll)
		{
			// No preparation needs to be done.
		}

		// Implements the IDataGridViewEditingControl
		// .RepositionEditingControlOnValueChange property.
		public bool RepositionEditingControlOnValueChange
		{
			get
			{
				return false;
			}
		}

		// Implements the IDataGridViewEditingControl
		// .EditingControlDataGridView property.
		public DataGridView EditingControlDataGridView
		{
			get
			{
				return dataGridView;
			}
			set
			{
				dataGridView = value;
			}
		}

		// Implements the IDataGridViewEditingControl
		// .EditingControlValueChanged property.
		public bool EditingControlValueChanged
		{
			get
			{
				return valueChanged;
			}
			set
			{
				valueChanged = value;
			}
		}

		// Implements the IDataGridViewEditingControl
		// .EditingPanelCursor property.
		public Cursor EditingPanelCursor
		{
			get
			{
				return base.Cursor;
			}
		}

		protected override void OnValueChanged(EventArgs eventargs)
		{
			// Notify the DataGridView that the contents of the cell
			// have changed.
			valueChanged = true;
			this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
			base.OnValueChanged(eventargs);
		}
	}
}
